# 交互式使用
# 为了方便诸如IPython之类的Python交互环境，可以使用InteractiveSession代替Session类
# 使用Tensor.eval()和Operation.run()方法替代Session.run()
# 这样可以避免使用一个变量来持有会话

# 进入一个交互式会话TensorFlow会话
import tensorflow as tf
sess = tf.InteractiveSession()

x = tf.Variable([1.0,2.0])
a = tf.constant([3.0,3.0])

# 使用初始化器initializer op的run()方法初始化x
x.initializer.run()

# 增加一个减法sub op，从x中减去a，运行减法op，输出结果
sub = tf.subtract(x,a)

print(sub.eval())

#
# Tensor
# TensorFlow程序使用tensor数据结构来代表所有的数据，计算图中，操作间传递的数据都是tensor。
# 你可以把TensorFlow tensor看着是一个n维的数组或列表。
# 一个tensor包含一个静态类型rank和一个shape
#
# 变量
# Varialbles for more details。
# 变量维护图执行过程中的状态信息
#

# 创建一个变量，初始化为标量0
state = tf.Variable(0,name="counter")

# 创建一个op，其作用是使得state增加1
one = tf.constant(1)
new_value = tf.add(state,one)
update = tf.assign(state,new_value)

# 启动图后，变量必须先经过初始化init op初始化
# 首先必须增加一个初始化 op到图中
init_op = tf.initialize_all_variables()

# 启动图，运行op
with tf.Session() as sess:
    #运行 init op
    sess.run(init_op)
    #打印state的初值
    print(sess.run(state))
    # 运行op，更新state，并打印state
    for _ in range(3):
        sess.run(update)
        print(sess.run(state))

# 代码中assign()操作是图所描绘的表达式的一部分，正如add()操作一样。
# 所以在调用run()执行表达式前，它不会真正的执行赋值操作
#
# 通常会将一个统计模型中的参数表示为一组变量。
# 例如，你可以将一个神经网络的权重作为某个变量存储在一个tensor中。
# 在训练过程中，通过重复运行训练图，更新这个tensor



#
# Fetch
# 为了取回操作的输出内容，可以在使用Session对象的run()调用执行图时，传入一些tensor
# 这些tensor会帮助你取回结果

# input_1 = tf.constant(3.0)
# input_2 = tf.constant(2.0)
# input_3 = tf.constant(5.0)
# intermed = tf.add(input_2,input_3)
# mul = tf.multiply(input_1,intermed)
#
# with tf.Session() as sess:
#     result = sess.run([mul,intermed])
#     print(result)

# 需要获取的多个tensor值，在op的一次运行中一起获得，而不是逐个去获取tensor



#
# Feed
# 上述示例中在计算图中引入了tensor，以变量或常量的形式存储
# TensorFlow还提供了feed机制，该机制可以临时替代图中的任意操作中的tensor，可以对途中任何操作提交补丁，直接插入一个tensor
# feed使用一个tensor值临时替换一个操作的输出结果
# 你可以提供feed数据作为run()调用的参数
# feed只在调用它的方法内有效，方法结束，feed就会消失
# 最常用的用例是将某些特殊的操作指定为feed操作，标记的方法是使用tf.placeholder()为这些操作创建占位符

input_1 = tf.placeholder(tf.float32)
input_2 = tf.placeholder(tf.float32)
output = tf.multiply(input_1,input_2)

with tf.Session() as sess:
    print(sess.run([output],feed_dict={input_1:[7.0],input_2:[3.]}))
# 输出
# [array([ 14.], dtype=float32)]
# for a larger-scale example of feeds.
# 如果没有正确提供feed，placeholder()操作将会产生错误
#